/************************************************************************

								Heroes IV
					  Copyright 2001, The 3DO Company

	------------------------------------------------------------------
				       ownable_garrisonable_adv_object.h

	$Header: $

	$NoKeywords: $

 ************************************************************************/

#if !defined( OWNABLE_GARRISONABLE_ADV_OBJECT_H_INCLUDED )
#define OWNABLE_GARRISONABLE_ADV_OBJECT_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <algorithm>
#include <iosfwd>

#include "creature_array.h"
#include "owned_adv_object.h"
#include "ownable_event_list.h"
#include "scriptable_event.h"
#include "sized_int_types.h"


// ---------------------------------------------------------------
// Base class for adventures object which can be owned and have
// a garrison, mainly mines and garrisons. Towns are not derived
// from here for "historically reasons" (a.k.a. they were implemented
// first and I'm not about to change that much code around)
// ---------------------------------------------------------------
class t_ownable_garrisonable_adv_object : public t_owned_adv_object, public t_creature_array
{
public:
	t_ownable_garrisonable_adv_object(  std::string const& source );

	bool						can_remove_garrison() const;
	void						copy_events( t_ownable_built_in_event_ptr built_in[ k_garrison_scriptable_event_count ],
											 t_ownable_continuous_event_list const& continuous,
											 t_ownable_timed_event_list const& timed,
											 t_ownable_triggerable_event_list const& triggerable);
	virtual	void				destroy();
	virtual t_skill_mastery		get_anti_stealth_level() const;
	t_creature_array&			get_garrison();
	t_creature_array const &	get_garrison() const;
	virtual t_ownable_garrisonable_adv_object*	get_ownable_garrison();
	virtual bool				get_virtual_position( t_adv_map_point& position ) const;
	virtual void				initialize( t_adventure_map& map );
	virtual bool				is_deleted_by_deletion_marker() const;
	virtual bool				is_triggered_by( t_creature_array const& army ) const;
	virtual void				on_begin_turn();
	virtual void				on_end_turn();
	virtual void				place( t_adventure_map& map, t_adv_map_point const& point );
	virtual bool				preplacement( t_adventure_map& map, int pass );
	virtual bool				process_continuous_events( t_adventure_map& map );
	virtual void				process_new_day();
	virtual bool				process_triggerable_events( t_adventure_map& map, std::string const& name );
	virtual bool				process_timed_events( t_adventure_map& map, bool start_of_day = true );
	virtual bool				read_from_map( std::streambuf& buffer, t_progress_handler* );
	virtual void				read_postplacement( t_adventure_map& map );
	void						run_garrison_dialog( t_army * visiting_army );
	virtual bool				select();
	virtual void				set_owner( int player_number );
	virtual bool			    write( std::streambuf& stream ) const;

protected:
	virtual int					compute_scouting_range() const;
	void						execute_script(t_garrison_scriptable_event event_id, t_army* army);
	void						place_gravestone();
	bool						read( std::streambuf&						stream, 
									  t_qualified_adv_object_type const&	type );
	bool						read_version( std::streambuf&						stream, 
									          t_qualified_adv_object_type const&	type,
											  int									version );
	bool						read_data_from_map( std::streambuf& buffer, t_uint16 format_version );
	void						set_can_remove_garrison( bool can_remove_garrison );

private:
	bool						read_built_in_events_from_map( std::streambuf& stream, t_uint16 format_version );
	bool						read_continuous_events_from_map( std::streambuf& stream, t_uint16 format_version );
	bool						read_events( std::streambuf& stream, int version );
	bool						read_garrison_from_map( std::streambuf& stream, t_uint16 format_version );
	bool						read_timed_events_from_map( std::streambuf& stream, t_uint16 format_version );
	bool						read_triggerable_events_from_map( std::streambuf& stream, t_uint16 format_version );
	bool						write_events( std::streambuf& stream ) const;

	t_ownable_built_in_event_ptr		m_built_in_events[ k_garrison_scriptable_event_count ];
	t_ownable_continuous_event_list		m_continuous_events;
	t_ownable_timed_event_list			m_timed_events;
	t_ownable_triggerable_event_list	m_triggerable_events;
	bool								m_can_remove_garrison; // Can the player move creatures out of the garrison?
};


// ---------------------------------------------------------------
// ---------------------------------------------------------------
inline bool t_ownable_garrisonable_adv_object::can_remove_garrison() const
{
	return m_can_remove_garrison;
}

// ---------------------------------------------------------------
// ---------------------------------------------------------------
inline t_creature_array& t_ownable_garrisonable_adv_object::get_garrison()
{
	return *this;
}

// ---------------------------------------------------------------
// ---------------------------------------------------------------
inline t_creature_array const & t_ownable_garrisonable_adv_object::get_garrison() const
{
	return *this;
}

// ---------------------------------------------------------------
// ---------------------------------------------------------------
inline void t_ownable_garrisonable_adv_object::set_can_remove_garrison( bool can_remove_garrison )
{
	m_can_remove_garrison = can_remove_garrison;
}

#endif // OWNABLE_GARRISONABLE_ADV_OBJECT_H_INCLUDED

